﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TsTreeTimeSeries.tstree;
using TsTreeTimeSeries.node;
using Telerik.WinControls.UI;
using TreeGenerator;
using System.Xml;
using System.IO;
using TsTreeTimeSeries.data;

using RTree;


namespace TsTreeTimeSeries
{
    public partial class Form2 : Form
    {
        #region Variables
        private TSTree tree;
        private R_Tree tree_r;
        private timeseriesData data = new timeseriesData() ;
        private int treeType;
        //public int test;
        private DataTable _rawData;
        List<tsObject> Objects = new List<tsObject>();

        private int _numNode;
        private int _internalNode;
        private int _leafNode;
        private int _totalEntries;
        private DateTime _runtime;
        private float _duration;

        public char[] symbols;
        int MAXVALUE = 500;
        int MINVALUE = 0;
        int DIMENSION = 20;
        int reductionRatio = 4;
        public DataTable rawData
        {
            get { return _rawData; }
            set { _rawData = value; }
        }

        #endregion

        #region Constructor
        public Form2()
        {
            InitializeComponent();

            CreateTree();
        }

        public Form2(DataTable rawData, char[] _symbols)
        {
            this.rawData = rawData;
            this.symbols = _symbols;
            tree = new TSTree();
            InitializeComponent();
     
        }


        private void Form2_Loaded(object sender, EventArgs e)
        {
            CreateTree();
            SetInfo4Tree();
            AssignInfo4Text();
        }

        #endregion

        #region Build tree

        public void AssignInfo4Text()
        {
            this.NodeNum.Text = this._numNode.ToString();
            this.NumberObjects.Text = this._totalEntries.ToString();
            this.InternalNodeNum.Text = this._internalNode.ToString();
            this.leafNodeNum.Text = this._leafNode.ToString();
            this.treeHeight.Text = tree.Height.ToString();
            this.ObjectPerNode.Text = ((float)this._totalEntries / this._numNode).ToString();
            this.avgTreeHeight.Text = ((float)this._numNode / this.tree.Height).ToString();
        }
        public void SetInfo4Tree()
        {
            this._numNode = tree.NodeMap.Count;
            for (int i = 0; i < tree.NodeMap.Count; i++)
            {
                Node temp = tree.NodeMap[i];
                if (temp.isLeaf())
                {
                    this._leafNode++;
                    this._totalEntries += temp.entryCount;
                }

            }
            this._internalNode = this._numNode - this._leafNode;
        }

        #region TS TREE
        public void CreateTree()
        {
            ParseData();
            PrepareData();
            BuildTree();
            PrintTree();
        }

       
        public void BuildTree()
        {
            for (int i = 0; i < Objects.Count; i++)
            {
                tree.InsertEntry(new Entry(Objects[i]), i, 1);
            }
        }
        // Prepare data : Quantization & PAA
        public void PrepareData()
        {
            try
            {
                foreach (tsObject o in Objects)
                {
                    o.PAA(reductionRatio);
                    o.Quantization(MAXVALUE, MINVALUE, symbols);
                }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.ToString());
            }

        }

        public void ParseData()
        {
            try
            {
                foreach (DataRow r in rawData.Rows)
                {
                    tsObject tempObject = new tsObject();
                    for (int i = 1; i < rawData.Columns.Count; i++)
                    {
                        tempObject.tsValueO.Add(float.Parse(r[i].ToString()));
                    }
                    Objects.Add(tempObject);
                }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.ToString());
            }
        }
        public void PrintTree()
        {
            tree.ParentsList.Clear();
            tree.ParentsList.Push(tree.RootNodeId);

            Node n = null;

            while (tree.ParentsList.Count > 0)
            {
                n = getNode(tree.ParentsList.Pop());
            
                // ADD NODE HERE
                if (n.nodeId == tree.RootNodeId)
                {
                    this.AddNode(this.radTreeView1.Nodes, n.nodeId, n.level, true);
                }
                else
                {
                    this.radTreeView1.SelectedNode = this.radTreeView1.GetNodeByName(n.parentNodeId.ToString());
                    RadTreeNode selectedNode = this.radTreeView1.SelectedNode;
                    if (selectedNode != null)
                    {
                        this.AddNode(selectedNode.Nodes, n.nodeId, n.level, false);
                        selectedNode.Expanded = true;
                    }
                }
                // ADD INFO HERE
                if (!n.isLeaf())
                {
                    //System.Console.WriteLine("NodeID" + n.nodeId.ToString() + "Level:" + n.level.ToString() + "SoEntries:" + n.entryCount.ToString());
                    string printInfoNode = n.nodeId.ToString() + ":";

                    for (int i = 0; i < n.entryCount; i++)
                    {
                        Entry tempEntry = n.getEntry(i);
                        printInfoNode += tempEntry.EntryToString();

                        getNode(n.ids[i]).parentNodeId = n.nodeId;
                        tree.ParentsList.Push(n.ids[i]);
                    }
                    this.radTreeView1.SelectedNode.Text = printInfoNode;
                }
                else
                {
                    //System.Console.WriteLine("NodeID" + n.nodeId.ToString() + "Level:" + n.level.ToString() + "SoEntries:" + n.entryCount.ToString());
                    string printInfoNode2 = n.nodeId.ToString() + ":";
                    for (int i = 0; i < n.entryCount; i++)
                    {
                        Entry tempEntry = n.getEntry(i);
                        printInfoNode2 += tempEntry.EntryToString();
                    }
                    this.radTreeView1.SelectedNode.Text = printInfoNode2;
                }
            }
        }

        private Node getNode(int index)
        {
            return (Node)tree.NodeMap[index];
        }

        private void UpdateButtonStates()
        {
            RadTreeNode selectedNode = this.radTreeView1.SelectedNode;
            bool enabled = selectedNode != null;

            //this.btnAddChild.Enabled = enabled;
            //this.btnRemove.Enabled = enabled;
        }

        private void AddNode(RadTreeNodeCollection nodes, int NameNode, int level, bool Isroot)
        {
            RadTreeNode newNode = new RadTreeNode();
            string path = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
            //System.Console.WriteLine(path);
            //newNode.Text = "RadTreeNode";
            nodes.Add(newNode);
            newNode.Name = NameNode.ToString();
            if (Isroot)
            {

                newNode.Image = Image.FromFile(path + @"\Asset\home_small.ico");

            }
            else
            {
                if (level == 1)
                {
                    newNode.Image = Image.FromFile(path + @"\Asset\flag_small.ico");
                }
                else
                {
                    newNode.Image = Image.FromFile( path + @"\Asset\burn_small.ico");
                }
            }
            this.radTreeView1.SelectedNode = newNode;
        }

        private void removeNode()
        {
            RadTreeNode selectedNode = this.radTreeView1.SelectedNode;
            if (selectedNode != null)
            {
                selectedNode.Remove();
            }
        }
        #endregion

        #region R-TREE

        #endregion

        #region R*-TREE
        #endregion

        #endregion



        #region Export Image

        // private TreeGenerator.
        //private TreeBuilder myTree = null;
        //private void ShowTree()
        //{

        //    picTree.Image = Image.FromStream(myTree.GenerateTree(-1, -1, "1", System.Drawing.Imaging.ImageFormat.Bmp));
        //    picTree.SizeMode = PictureBoxSizeMode.StretchImage;
        //    //picTree.Image.Save(@"d:\temp\1.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);


        //}

        //private void picOrgChart_MouseClick(object sender, MouseEventArgs e)
        //{
        //    Rectangle currentRect;
        //    //determine if the mouse clicked on a box, if so, show the  node description.
        //    string SelectedNode = "No Node";
        //    //find the node
        //    foreach (XmlNode oNode in myTree.xmlTree.SelectNodes("//Node"))
        //    {
        //        //iterate through all nodes until found.
        //        currentRect = myTree.getRectangleFromNode(oNode);
        //        if (e.X >= currentRect.Left &&
        //            e.X <= currentRect.Right &&
        //            e.Y >= currentRect.Top &&
        //            e.Y <= currentRect.Bottom)
        //        {
        //            SelectedNode = oNode.Attributes["nodeDescription"].InnerText;
        //            break;
        //        }


        //    }

        //    //MessageBox.Show(SelectedNode);
        //    //lblNodeText.Text = string.Format("Last Clicked:{0}", SelectedNode);
        //}

        //private void btnShowChart_Click(object sender, EventArgs e)
        //{
        //    ShowTree();

        //}

        //private TreeData.TreeDataTableDataTable GetTreeData()
        //{
        //    TreeData.TreeDataTableDataTable dt = new TreeData.TreeDataTableDataTable();
        //    dt.AddTreeDataTableRow("1", "", "RootNode", "This is your Local Server");
        //    dt.AddTreeDataTableRow("2", "1", "Child 0", "This is the second child.");
        //    dt.AddTreeDataTableRow("3", "1", "Child 1", "This is the second child.");
            //dt.AddTreeDataTableRow("2", "6", "Child 2", "This is the first child.");
            //dt.AddTreeDataTableRow("3", "5", "Child 3", "This is the second child.");
            //dt.AddTreeDataTableRow("4", "2", "Child 4", "This is the second child.");
            //dt.AddTreeDataTableRow("5", "6", "Child 5", "This is the second child.");
           

            //dt.AddTreeDataTableRow("4", "1", "Child 3", "This is the third child.");
            //dt.AddTreeDataTableRow("5", "2", "GrandChild 1", "This is the only Grandchild.");
            //for (int i = 6; i < 150; i++)
            //{
            //    Random rand = new Random();
            //    dt.AddTreeDataTableRow(i.ToString(), rand.Next(1, i).ToString(), "GrandChild " + i.ToString(), "This is the only Grandchild.");
            //}
        //    return dt;
        //}


        //private void ZoomInOut(bool zoom)
        //{
        //    //Zoom ratio by which the images will be zoomed by default
        //    int zoomRatio = 10;
        //    //Set the zoomed width and height
        //    int widthZoom = picTree.Width * zoomRatio / 100;
        //    int heightZoom = picTree.Height * zoomRatio / 100;
        //    //zoom = true --> zoom in
        //    //zoom = false --> zoom out
        //    if (!zoom)
        //    {
        //        widthZoom *= -1;
        //        heightZoom *= -1;
        //    }
        //    //Add the width and height to the picture box dimensions
        //    picTree.Width += widthZoom;
        //    picTree.Height += heightZoom;


        //}
        #endregion
        
        #region Events
        private void label10_Click(object sender, EventArgs e)
        {

        }

        private void SelectedNodeChanged(object sender, RadTreeViewEventArgs e)
        {

        }
        #endregion
        // nap xml
        private void button3_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog(); 
            openFileDialog.AddExtension = true; 
            openFileDialog.DefaultExt = ".xml"; 
            openFileDialog.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*"; 
            openFileDialog.Multiselect = false; 
            if (openFileDialog.ShowDialog() == DialogResult.OK) 
            { 
                this.radTreeView1.LoadXML(openFileDialog.FileName); 
            } 
        }
        // save xml
        private void button1_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog(); 
            saveFileDialog.AddExtension = true; 
            saveFileDialog.DefaultExt = ".xml"; 
            saveFileDialog.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*"; 
            if (saveFileDialog.ShowDialog() == DialogResult.OK) 
            { 
                this.radTreeView1.SaveXML(saveFileDialog.FileName); 
            }
        }
        // show image
        private void button5_Click(object sender, EventArgs e)
        {

        }
        // save result
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                data.RunStoredProc(this.treeType, this._runtime, this._numNode, this._internalNode, this._leafNode, this._totalEntries, this.tree.Height, (float)this._totalEntries / this._numNode, (float)this._numNode / this.tree.Height, this._duration);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        // show chart
        private void button2_Click(object sender, EventArgs e)
        {
            Form3 f = new Form3();
            f.Show();
        }

    }
}
